package com.jh3502.vivo.base;

import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.jh3502.vivo.Jh3502HelperApplication;
import com.jh3502.vivo.R;
import com.jh3502.vivo.utils.ActivityTracker;
import com.jh3502.vivo.utils.Constant;
import com.jh3502.vivo.utils.UploadHelper;
import com.jh3502.vivo.utils.VersionUpdataHelper;
import com.jh3502.vivo.utils.eventbus.EventBusHelper;
import com.jh3502.vivo.utils.eventbus.EventBusMessage;
import com.jh3502.vivo.utils.jpush.JPushSetUitl;
import com.jh3502.vivo.view.SnackbarUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import butterknife.ButterKnife;
import cxy.com.validate.Validate;
import me.imid.swipebacklayout.lib.SwipeBackLayout;
import me.imid.swipebacklayout.lib.app.SwipeBackActivity;
import pub.devrel.easypermissions.EasyPermissions;


/**
 * @author harisucici
 * @date 07.03
 */

public abstract class BaseActivity<V, T extends BasePresenter<V>> extends SwipeBackActivity implements BaseView, EasyPermissions.PermissionCallbacks {
    private static final String TAG = "BaseActivity";
    public Jh3502HelperApplication mJh3502HelperApplication;
    public File mCamareFile;
    public JPushSetUitl jPushSetUitl;
    protected File mVideoCameraFile;
    protected AMapLocationClient locationClient;
    protected AMapLocationClientOption locationOption;
    protected T mPresenter;
    // 定位监听
    AMapLocationListener locationListener = location -> {
        if (null != location) {
            if (location.getLongitude() > 1) {
                Jh3502HelperApplication.setMapLocation(location);
                stopLocation();
                EventBusHelper.sendEventBusMsg(EventBusHelper.LOCATION_SUCCESS);
                Log.i(TAG, "定位服务运行成功并拿到了数据---loc=== " + location.getAddress());
            } else {
                Log.i(TAG, "定位服务运行成功，数据异常---loc为0=== " + location.toString());
            }
        } else {
            Log.i(TAG, "定位服务启动失败---loc is null===");
        }
    };
    private ProgressDialog progressDialog;
    private SwipeBackLayout mSwipeBackLayout;

    public abstract T initPresenter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mPresenter = initPresenter();
        if (progressDialog == null) {
            progressDialog = new ProgressDialog();
        }

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        super.onCreate(savedInstanceState);
        mSwipeBackLayout = getSwipeBackLayout();
        mSwipeBackLayout.setEdgeTrackingEnabled(SwipeBackLayout.EDGE_LEFT);
        ActivityTracker.getInstance().onCreate(this);
        mJh3502HelperApplication = (Jh3502HelperApplication) getApplication();
        jPushSetUitl = JPushSetUitl.getPushSetUitl(this);
        setContentView(setViewId());
        ButterKnife.bind(this);
        Validate.reg(this);
        initView();
        initData();
        //强制横竖
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        showShortToast("权限请求成功!");
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        showShortToast("权限请求失败!");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.i("BaseActivity", "onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mPresenter != null) {
            mPresenter.attachView((V) this);
        }
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        doOnResume();
        Log.i("BaseActivity", "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.i("BaseActivity", "onPause");
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) {
            mPresenter.detachView();
        }
        Validate.unreg(this);
        EventBus.getDefault().unregister(this);
        ActivityTracker.getInstance().onDestory(this);
        destroyLocation();
        doOnDestroy();
        Log.i("BaseActivity", "onDestroy");


    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        doOnSaveInstanceState(savedInstanceState);
        Log.i("BaseActivity", "onSaveInstanceState");
    }

    protected abstract int setViewId();

    protected abstract void initView();

    protected abstract void initData();

    protected abstract void doOnDestroy();

    protected abstract void doOnResume();

    protected abstract void doOnSaveInstanceState(Bundle savedInstanceState);

    @Subscribe
    public void onEventMainThread(@NonNull EventBusMessage eventBusMessage) {
        if (eventBusMessage.getCode() == Constant.SESSION_TIMEOUT) {
//            showShortToast("登录状态失效，请重新登录");
//            SpHelper.getInstance().clearAll();
//            Utils.getInstance().startActivity(this, LoginActivity.class, null, false);
//            ActivityTracker.getInstance().finishAll();
        }
    }

    @Override
    public void showLoadingDialog() {
//        showLoadingDialog(null, "请等待");
        if (progressDialog.getTag() == null) {
            progressDialog.show(getSupportFragmentManager(), "progress");
        }
    }

    @Override
    public void dismissLoadingDialog() {
        if (progressDialog != null) {
            progressDialog.dismiss();
        }

    }

    @NonNull
    @Override
    public Context getActContext() {
        return this;
    }

    public void showShortToast(@NonNull String message) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }

        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, SnackbarUtil.INFO);
    }

    public void showShortToast(@NonNull String message, int type) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, type);
    }

    protected void showLongToast(@NonNull String message, String info, @NonNull View.OnClickListener listener, int type) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
        }
        SnackbarUtil.showBarLongTime(findViewById(android.R.id.content), message, type, info, listener);
    }

    public void chooseLocImage() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        startActivityForResult(intent, Constant.REQUEST_CODE_IMAGE);
    }

    public void chooseLocCamera(String path) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Jh3502/" + path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式在android中，创建文件时，文件名中不能包含“：”冒号
        String filename = df.format(new Date());
        mCamareFile = new File(dir, filename + ".png");
        if (!mCamareFile.exists()) {
            try {
                mCamareFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        selectImageFromCamera(Constant.REQUEST_CODE_CAMERA, mCamareFile);
    }

    public void selectImageFromCamera(int requestCode, @Nullable File saveImage) {
        if (saveImage == null) {
            Log.i(TAG, "Image file parameter is null.");
            saveImage = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".png");
        }
        int currentapiVersion = Build.VERSION.SDK_INT;
        Log.i(TAG, "---currentapiVersion===" + currentapiVersion);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (currentapiVersion < Build.VERSION_CODES.N) {
            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(saveImage));
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        } else {
            if (saveImage.exists()) {
                try {
                    saveImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Images.Media.DATA, saveImage.getAbsolutePath());
            Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        }
        startActivityForResult(intent, requestCode);
    }

    protected void chooseLocVideo() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("video/*");
        startActivityForResult(intent, Constant.REQUEST_CODE_VIDEO);
    }

    public void getImageFromCamera() {
        mCamareFile = UploadHelper.getInstance().getCameraSaveFile(this, System.currentTimeMillis());
        UploadHelper.getInstance().selectImageFromCamera(this, Constant.REQUEST_CODE_CAMERA, mCamareFile);
    }

    public void saveImageFromCamera(String path) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Jh3502/" + path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式在android中，创建文件时，文件名中不能包含“：”冒号
        String filename = df.format(new Date());
        mCamareFile = new File(dir, filename + ".png");
        if (!mCamareFile.exists()) {
            try {
                mCamareFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        UploadHelper.getInstance().selectImageFromCamera(this, Constant.REQUEST_CODE_CAMERA, mCamareFile);
    }

    public void getVideoFromCamera() {
        mVideoCameraFile = UploadHelper.getInstance().getCameraSaveVideoFile(this, System.currentTimeMillis());
        UploadHelper.getInstance().selectVideoFromCamera(this, Constant.REQUEST_CODE_VIDEO_CAMERA, mVideoCameraFile);
    }


    @Override
    public void requestFailure(@NonNull Throwable t) {
        if (t.toString().contains(Constant.TIMEOUT_EXCEPTION)) {
            showShortToast(getString(R.string.servicer_no_response));
        }
    }

    public void showInteractionDialog(String msg, DialogInterface.OnClickListener okListener) {
        showInteractionDialog(msg, true, "确认", "取消", okListener, (dialog, which) -> dialog.dismiss());
    }

    public void showInteractionDialog(String msg, boolean cancelable, String ok, String no,
                                      DialogInterface.OnClickListener okListener,
                                      DialogInterface.OnClickListener noListener) {
        VersionUpdataHelper.CustomDialog.Builder builder = new VersionUpdataHelper.CustomDialog.Builder(this);
        builder.setMessage(msg);
        builder.setPositiveButton(ok, okListener);
        if (!TextUtils.isEmpty(no)) {
            builder.setNegativeButton(no, noListener);
        }
        VersionUpdataHelper.CustomDialog dialog = builder.create();
        dialog.setCancelable(cancelable);
        dialog.show();
    }

    protected boolean checkPermission(String... permissions) {
        if (permissions.length == 0) {
            return EasyPermissions.hasPermissions(this, Constant.PERMISSIONS);
        } else {
            return EasyPermissions.hasPermissions(this, permissions);
        }
    }

    protected void requestPermission(String... permissions) {
        if (permissions.length == 0) {
            EasyPermissions.requestPermissions(this,
                    getString(R.string.permission_rationale),
                    Constant.REQUEST_PERMISSION_CODE,
                    Constant.PERMISSIONS);
        } else {
            EasyPermissions.requestPermissions(this,
                    getString(R.string.permission_rationale),
                    Constant.REQUEST_PERMISSION_CODE,
                    permissions);
        }
    }


    /**
     * 初始化定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected void initLocation(@Nullable AMapLocationListener listener) {
        //初始化client
        locationClient = new AMapLocationClient(this.getApplicationContext());
        locationOption = getDefaultOption();
        //设置定位参数
        locationClient.setLocationOption(locationOption);
        // 设置定位监听
        if (listener == null) {
            locationClient.setLocationListener(locationListener);
        } else {
            locationClient.setLocationListener(listener);
        }
        startLocation();
    }

    /**
     * 默认的定位参数
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    @NonNull
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setGpsFirst(true);
        //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setHttpTimeOut(30000);
        //可选，设置定位间隔。默认为2秒
        mOption.setInterval(3000);
        //可选，设置是否返回逆地理地址信息。默认是true
        mOption.setNeedAddress(true);
        //可选，设置是否单次定位。默认是false
        mOption.setOnceLocation(false);
        //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        mOption.setOnceLocationLatest(false);
        //可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTPS);
        //可选，设置是否使用传感器。默认是false
        mOption.setSensorEnable(false);
        //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setWifiScan(true);
        //可选，设置是否使用缓存定位，默认为true
        mOption.setLocationCacheEnable(true);
        return mOption;
    }

    /**
     * 开始定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected void startLocation() {
        Log.i(TAG, "---startLocation===");
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        // 启动定位
        locationClient.startLocation();
    }

    /**
     * 停止定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected void stopLocation() {
        // 停止定位
        locationClient.stopLocation();
    }

    /**
     * 销毁定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }

}
